<?php
/**
 * Created by PhpStorm.
 * User: yiyu
 * Email: smalleasyu@gmail.com
 * Date: 2020-01-28 22:08:51
 * Desc:
 */

namespace app\api\service;

use app\base\service\BaseService;
use app\base\model\goods\{GoodsBaseInfo, GoodsGroupInfo, GoodsGroupJoinInfo};
use app\base\model\user\{UserFriend, UserStatisticsInfo};
use app\base\model\user\User;
use app\core\exception\BusinessException;
use app\core\exception\ErrorCode;
use app\core\log\Log4dd;

class WishRecommendService extends BaseService
{

    const MENU_KEY_CIRCLE = 'circle';
    const MENU_KEY_CIRCLE_NAME = '圈子';
    const MENU_KEY_SQUARE = 'square';
    const MENU_KEY_SQUARE_NAME = '广场';
    const MENU_KEY_SQUARE_RECOMMEND = 'square_recommend';
    const MENU_KEY_SQUARE_RECOMMEND_NAME = '推荐';
    const MENU_KEY_SQUARE_NEW = 'square_new';
    const MENU_KEY_SQUARE_NEW_NAME = '最新';

    public $user_infos = [];
    public $user_statistics_infos = [];
    public $goods_infos = [];

    const GET_WISH_SCENE_PRODUCT = 'product';
    const GET_WISH_SCENE_EXCHANGE = 'exchange';

    /**
     * Desc: 首页 - 圈子 心愿列表排序
     * 按用户发表顺序
     * Date: 2020/2/16 18:25
     * Author: yiyu
     * @param $user_id
     * @return array
     */
    public static function getCircleList($user_id)
    {
        //获取我的好友
        $friend_ids = UserFriend::getMyFriend($user_id);

        array_push($friend_ids, $user_id);//需要显示自己的

        $sort_where = [
            'need_join_people' => 0, //支持人数为0的是否放前面
            'need_exclude_self' => 0,//是否排除自己已帮付过款的
            'need_time' => true,//是否需要显示发表时间
            'need_success_num' => false,//是否需要按成单次数进行排序
            'need_wait_time' => false
        ];//是否需要按成单次数进行排序

        $friend_result_items = $common_result_items = [];
        //获取好友未达成的心愿
        if ($friend_ids) {
            $friend_wish_items = GoodsGroupInfo::getInitiateDetailListByUserIds(
            [
                'g.group_state' => ['<=', GoodsGroupInfo::GROUP_SUCCESS_STATE],
                'g.user_id' => ['in', $friend_ids]
            ],
            ['g.create_time' => 'DESC']
            );

            $friend_result_items = self::sortWish($user_id, $friend_wish_items, $sort_where);
        }

        return $friend_result_items;
    }

    public static function circleHaveData($user_id)
    {
        $friend_ids = UserFriend::getMyFriend($user_id);

        if ($friend_ids) {
            $count = GoodsGroupInfo::getWishNumByUserIds(['user_id' => ['in', $friend_ids]]);

            return $count ? true : false;
        }

        return false;
    }

    /**
     * Desc: 首页 - 广场 - 推荐 心愿列表排序
     * 以下两条为上下包含关系，按照优先级从上往下排序，一次加载 15 条心愿（包含自己帮付过款的）
     *  第一优先级，按照用户是否达成过心愿：优先展示从未达成过心愿的用户的心愿
     *  第二优先级，按照等待支持时间：优先显示等待支持时间最长的心愿，等待支持时间=当前时间-该心愿 上一次被支持的时间（如果心愿从未被支持，则为心愿发起时间）
     * Date: 2020/2/16 18:07
     * Author: yiyu
     * @param $user_id
     * @return array|false|\PDOStatement|string|\think\Collection
     */
    public static function getSquareRecommendList($user_id)
    {

        $items = GoodsGroupInfo::getInitiateList(['g.user_id' => ['<>', $user_id], 'g.group_state' => ['<', GoodsGroupInfo::GROUP_SUCCESS_STATE]]);

        $sort_where = ['need_exclude_self' => 0, 'need_time' => false];//不排除自己帮付过款的,不需要显示时间

        $items = self::sortWish($user_id, $items, $sort_where);

        return array_slice($items, 0 ,1);//只要1个数据
    }

    /**
     * Desc: 首页 - 广场 - 最新 心愿列表排序
     * Date: 2020/2/16 18:19
     * Author: yiyu
     * @param int $user_id
     * @param array $where
     * @param array $order
     * @return false|\PDOStatement|string|\think\Collection
     */
    public static function getSquareNewList($user_id, $where = [], $order = [])
    {

        if (!isset($where['g.group_state'])) {
            $where['g.group_state'] = ['<=', GoodsGroupInfo::GROUP_SUCCESS_STATE];
        }

        if (empty($order)) {
            $order = [
                'g.create_time' => 'desc'
            ];
        }
        $items = GoodsGroupInfo::getInitiateList($where, $order);
        Log4dd::info('获取首页数据', $where);
        $sort_where = [
            'need_join_people' => 0, //支持人数为0的是否放前面
            'need_exclude_self' => 0,//是否排除自己已帮付过款的
            'need_time' => true,//是否需要显示发表时间
            'need_success_num' => false,//是否需要按成单次数进行排序
            'need_wait_time' => false
        ];

        $items = self::sortWish($user_id, $items, $sort_where);

        return $items;
    }

    public static function getExchangeModuleWishList($user_id)
    {

        $friend_ids = UserFriend::getMyFriend($user_id);

        $sort_where = ['need_join_people' => 1, 'need_exclude_self' => 1];//当前支持人数为0的一定要放前面 需要排除自己帮付过款的

        $friend_result_items = $common_result_items = [];
        //获取好友未达成的心愿
        if ($friend_ids) {
            $friend_wish_items = GoodsGroupInfo::getInitiateDetailListByUserIds([
                'g.group_state' => GoodsGroupInfo::GROUP_RUN_STATE,
                'g.can_free_support' => 0,
                'g.user_id' => ['in', $friend_ids]
            ], ['g.join_people' => 'asc', 'g.create_time' => 'asc']);

            $friend_result_items = self::sortWish($user_id, $friend_wish_items, $sort_where);
        }

        array_push($friend_ids, $user_id);//不需要显示自己的

        $common_wish_items = GoodsGroupInfo::getInitiateDetailListByUserIds([
            'g.group_state' => GoodsGroupInfo::GROUP_RUN_STATE,
            'g.can_free_support' => 0,
            'g.user_id' => ['not in', $friend_ids]
        ], ['g.join_people' => 'asc', 'g.create_time' => 'asc']);

        $common_result_items = self::sortWish($user_id, $common_wish_items, $sort_where);

        $result = array_merge($friend_result_items, $common_result_items);

        return self::buildWishListStructure($result);

    }

    public static function getWishListByGoodsId($user_id, $goods_id, $wish_num, $need_num = 15)
    {
        //$default_gold_give_ratio = GoodsService::getDefaultGoldGiveRatio();

        //获取只支持一个心愿即可满足心愿值的心愿列表
        $items = GoodsGroupInfo::field("group_id,goods_id,user_id,my_wish,need_people,join_people,group_total_price,group_curr_pay_price,group_total_price/need_people as can_get_wish_num")
            ->where('user_id','<>', $user_id)
            ->where('goods_id', $goods_id)
            ->where('group_state', GoodsGroupInfo::GROUP_RUN_STATE)
            ->select();

        $result_items = self::sortWish($user_id, $items, ['need_exclude_self' => 1]);//排除自己已帮付过款的

        $result_items = array_slice($result_items, 0, $need_num);

        $result = self::buildWishListStructure($result_items);

        return $result;
    }


    /**
     * Desc: 根据心愿值获取心愿列表
     * Date: 2020/2/14 8:23
     * Author: yiyu
     * @param $user_id
     * @param $wish_num
     * @param int $need_num
     * @return array
     */
    public static function getWishListByWishCoinNum($user_id, $wish_num, $need_num = 30)
    {


        Log4dd::info('根据心愿值获取心愿列表', func_get_args());
        $friend_ids = UserFriend::getMyFriend($user_id);

        $sort_where = ['need_join_people' => 1, 'need_exclude_self' => 1];//当前支持人数为0的需要一定要放前面 需要排除自己帮付过款的

        $friend_result_items = $common_result_items = [];
        //获取好友未达成的心愿
        if ($friend_ids) {
            $friend_wish_items = GoodsGroupInfo::getInitiateDetailListByUserIds([
                'g.group_state' => GoodsGroupInfo::GROUP_RUN_STATE,
                'g.can_free_support' => 0,
                'g.user_id' => ['in', $friend_ids]
            ], ['g.join_people' => 'asc', 'g.create_time' => 'asc']);

            $friend_result_items = self::sortWish($user_id, $friend_wish_items, $sort_where);
        }

        array_push($friend_ids, $user_id);//不需要显示自己的

        $common_wish_items = GoodsGroupInfo::getInitiateDetailListByUserIds([
            'g.group_state' => GoodsGroupInfo::GROUP_RUN_STATE,
            'g.can_free_support' => 0,
            'g.user_id' => ['not in', $friend_ids]
        ], ['g.join_people' => 'asc', 'g.create_time' => 'asc']);

        $common_result_items = self::sortWish($user_id, $common_wish_items, $sort_where);

        $result_items = array_merge($friend_result_items, $common_result_items);

        Log4dd::info('根据心愿值获取心愿列表1', count($result_items));

        $items = self::buildWishListStructure($result_items);

        $count = 0;

        $res = [];

        if ($items) {
            foreach ($items as $key => &$item) {
                if ($count > $wish_num && $key >= $need_num - 1) {
                    break;
                }

                if ($count > $wish_num) {
                    $item['is_select'] = 0;
                } else {
                    $item['is_select'] = 1;
                }

                //默认选中一个
                if ($key == 0 && $item['is_select'] == 0) {
                    $item['is_select'] = 1;
                }

                $count += $item['can_get_wish_coin_num'];

                $res[] = $item;
            }
        }

        Log4dd::info('根据心愿值获取心愿列表2', count($res));

        return $res;
    }


    /**
     * Desc: 心愿排序，
     * Date: 2020/2/15 10:09
     * Author: yiyu
     * @param $user_id
     * @param $wish_items
     * @param array $sort_where
     * @param int $sort_type
     * @return array
     */
    public static function sortWish($user_id, $wish_items, $sort_where = [], $sort_type = 1)
    {

        if (empty($wish_items)) {
            return [];
        }

        $curr_time = time();

        $result = [];

        $sort_arr = [];

        $need_join_people = $sort_where['need_join_people'] ?? 0;//当前支持人数为0的是否放前面
        $need_exclude_self = $sort_where['need_exclude_self'] ?? 1;//是否排除自己已帮付过款的 默认排除
        $need_time = $sort_where['need_time'] ?? true;//是否需要显示发表时间 默认显示
        $need_success_num = $sort_where['need_success_num'] ?? true;//是否需要按成单次数进行排序
        $need_wait_time = $sort_where['need_wait_time'] ?? true;//是否需要按成单次数进行排序


        foreach ($wish_items as $item) {
            $sort_num = strtotime($item['create_time']);
            $res = &$item;
            $res['create_time'] = formatTime($item['create_time']);
            if ($need_time == false) {
                $res['create_time'] = '';
            }

            $res['timestamp'] = $sort_num;

            $res['is_me'] = ($user_id == $item['user_id'] ? 1 : 0);//是否是自己的心愿

            //当前支持人数为0的一定要放前面
            if ($need_join_people && $item['join_people'] == 0) {
                $sort_num += 100000;
            }

            $join_id = GoodsGroupJoinInfo::getGroupJoinUserInfoByUserId($item['group_id'], $user_id);

            $res['i_had_support'] = $join_id ? 1 : 0;
            //排除自己已加入过的
            if ($need_exclude_self == 1) {
                if ($join_id) {
                    continue;
                }
            }

            if ($need_success_num) {
                $success_num = self::instance()->getUserWishSuccessNum($item['user_id']);
                $sort_num += 10000 - 10 * $success_num;//成单次数越小，值越大
            }

            if ($need_wait_time) {
                $wait_time = strtotime($item['create_time']);

                //获取最后一次被支持的时间
                if ($item['join_people'] > 0) {
                    $last_be_support_time = GoodsGroupJoinInfo::where('group_id', $item['group_id'])->order('join_id', 'desc')->value('update_time');
                    if ($last_be_support_time) {
                        $wait_time = strtotime($last_be_support_time);
                    }
                }

                $sort_num += $curr_time - $wait_time;//等待时间越长，值越大
            }

            $sort_arr[] = $sort_num;
            $result[] = $res;
        }

        array_multisort($sort_arr, ($sort_type == 1 ? SORT_DESC : SORT_ASC), $result);

        return $result;

    }


    /**
     * Desc: 组装数据结构
     * Date: 2020/2/16 23:15
     * Author: yiyu
     * @param $wish_items
     * @return array
     */
    public static function buildWishListStructure($wish_items)
    {

        $result = [];
        if(empty($wish_items)){
            return $result;
        }

        foreach($wish_items as $key => $item) {
            $user_info = self::instance()->getUserInfo($item['user_id']);
            $goods_info = self::instance()->getGoodsInfo($item['goods_id']);
            $need_pay_money = GoodsService::calculateNeedPayMoney($item);
            $result[] = [
                'nick_name' => $user_info['nick_name'],
                'avatar_url' => $user_info['small_avatar_url'],
                'goods_name' => $goods_info['goods_name'],
                'group_id' => $item['group_id'],
                'need_pay_money' => $need_pay_money,
                'can_get_wish_coin_num' => GoodsService::calculateCanGetWishCoinNum($need_pay_money),
                'need_people' => $item['need_people'],
                'join_people' => $item['join_people'],
                'is_select' => $key == 0 ? 1 : 0
            ];
        }

        return $result;

    }

    public function getUserWishSuccessNum($user_id)
    {
        if (!isset($this->user_statistics_infos[$user_id])) {
            $success_num = UserStatisticsInfo::where('user_id', $user_id)->value('success_num');
            $this->user_statistics_infos[$user_id]['success_num'] = (int)$success_num;
        }

        return $this->user_statistics_infos[$user_id]['success_num'];
    }

    public function getGoodsInfo($goods_id)
    {
        if (!isset($this->goods_infos[$goods_id])) {
            $info = GoodsBaseInfo::getGoodsBaseInfo($goods_id, ['goods_name']);
            $this->goods_infos[$goods_id] = $info;
        }

        return $this->goods_infos[$goods_id];
    }

    public function getUserInfo($user_id)
    {
        if (!isset($this->user_infos[$user_id])) {
            $info = User::getUserInfoById($user_id, ['nick_name', 'small_avatar_url']);
            $this->user_infos[$user_id] = $info;
        }

        return $this->user_infos[$user_id];
    }


}